package com.jackeys.piaems.service.impl;

import com.jackeys.piaems.dao.UserDao;
import com.jackeys.piaems.dto.UserInfDto;
import com.jackeys.piaems.entity.User;
import com.jackeys.piaems.service.UserService;
import com.jackeys.piaems.util.*;
import com.jackeys.piaems.vo.ResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * @ClassName: UserServiceImpl
 * @Description: 用户业务层接口实现类
 * @Author: Jackeys
 * @Date: 2021-06-08 17:41
 * @Version: 1.0
 */
@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    private String code = null;

    /**
     * @Name: getUserInfById
     * @Description: 获取用户信息，实现查询用户信息功能
     * @Param: [id]
     * @return: java.util.List<com.jackeys.piaems.entity.User>
     * @Author: Jackeys
     * @Date: 2021/6/11 14:04
     * @Version: 1.0
     */
    @Override
    public ResponseVo getUserInfByAccount(String account) {
        log.debug("=====================================================================");
        log.debug("查询用户账号为" + account + "的个人信息");
        List<User> userList = userDao.getUserInfByAccount(account);
        if (userList == null || userList.size() == 0) {
            log.debug("查询失败：不存在用户账号为" + account);
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.GET_USER_FAIL);
        }
        log.debug("查询成功");
        User user = userList.get(0);
        UserInfDto userInfDto = new UserInfDto.Builder()
                .id(user.getId())
                .account(user.getAccount())
                .age(user.getAge())
                .birthday(user.getBirthday())
                .email(user.getEmail())
                .sex(user.getSex())
                .headPortrait(user.getHeadPortrait())
                .name(user.getName())
                .password(user.getPassword())
                .phone(user.getPhone())
                .sign(user.getSign())
                .build();
        log.debug("=====================================================================");
        return new ResponseVo(StatusEnumUtil.GET_USER_SUCCESS).add("user", userInfDto);
    }


    /**
     * @Name: login
     * @Description: 判断用户是否登陆成功，实现登陆功能
     * @Param: [account, password]
     * @return: com.jackeys.piaems.entity.User
     * @Author: Jackeys
     * @Date: 2021/6/11 14:04
     * @Version: 1.0
     */
    @Override
    public ResponseVo login(String account, String password) {
        log.debug("=====================================================================");
        log.debug("验证用户登陆");
        List<User> userList = userDao.login(account, password);
        if (userList == null || userList.size() == 0) {
            log.debug("登录失败：账号或者密码错误");
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.USER_LOGIN_FAIL);
        }
        User user = userList.get(0);
        UserInfDto userInfDto = new UserInfDto.Builder()
                .id(user.getId())
                .account(user.getAccount())
                .age(user.getAge())
                .birthday(user.getBirthday())
                .email(user.getEmail())
                .sex(user.getSex())
                .headPortrait(user.getHeadPortrait())
                .name(user.getName())
                .password(user.getPassword())
                .phone(user.getPhone())
                .sign(user.getSign())
                .build();
        String token = JwtUtil.createToken(userInfDto.getAccount(), userInfDto.getPassword());
        ResponseVo responseVo = new ResponseVo(StatusEnumUtil.USER_LOGIN_SUCCESS);
        responseVo.add("user", userInfDto);
        responseVo.add("token", token);
        log.debug("登陆成功");
        log.debug("=====================================================================");
        return responseVo;
    }


    /**
     * @Name: register
     * @Description: 判断用户注册是否成功，实现注册功能
     * @Param: [password, email]
     * @return: com.jackeys.piaems.vo.ResponseVo
     * @Author: Jackeys
     * @Date: 2021/6/14 19:32
     * @Version: 1.0
     */
    @Override
    public ResponseVo register(String password, String email, String securityCode) {
        log.debug("=====================================================================");
        log.debug("进行用户注册");
        if (!securityCode.equals(code)) {
            log.debug("注册失败：验证码错误");
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.USER_REGISTER_SECURITY_CODE_ERROR);
        }
        String account = String.valueOf(SnowFlakeIdUtil.nextId());
        Boolean flag1 = userDao.isEmailConflict(email) != 0;
        if (flag1) {
            log.debug("注册失败：邮箱冲突");
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.USER_REGISTER_EMAIL_CONFLICT);
        }
        Boolean flag2 = userDao.register(account, password, email);
        if (flag2) {
            log.debug("注册成功：发放账号：" + account);
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.USER_REGISTER_SUCCESS).add("account", account);
        }
        log.debug("注册失败：服务器异常");
        log.debug("=====================================================================");
        return new ResponseVo(StatusEnumUtil.USER_REGISTER_FAIL);
    }


    /**
     * @Name: forget
     * @Description: 判断用户找回密码是否成功，实现找回密码功能
     * @Param: [account, password]
     * @return: com.jackeys.piaems.vo.ResponseVo
     * @Author: Jackeys
     * @Date: 2021/6/14 19:33
     * @Version: 1.0
     */
    @Override
    public ResponseVo forget(String email, String password, String securityCode) {
        log.debug("=====================================================================");
        log.debug("进行用户忘记密码");
        if (!securityCode.equals(code)) {
            log.debug("忘记失败：验证码错误");
            log.debug("=====================================================================");

            return new ResponseVo(StatusEnumUtil.USER_FORGET_SECURITY_CODE_ERROR);
        }
        Boolean flag = userDao.forget(email, password);
        if (flag) {
            log.debug("忘记密码成功");
            log.debug("=====================================================================");

            return new ResponseVo(StatusEnumUtil.USER_FORGET_PASSWORD_SUCCESS);
        }
        log.debug("忘记密码失败：服务器异常");
        log.debug("=====================================================================");

        return new ResponseVo(StatusEnumUtil.USER_FORGET_PASSWORD_FAIL);
    }

    /**
     * @Name: sendSecurityCode
     * @Description: 发送验证码，实现发送验证码的功能
     * @Param: [email, code]
     * @return: com.jackeys.piaems.vo.ResponseVo
     * @Author: Jackeys
     * @Date: 2021/6/22 16:45
     * @Version: 1.0
     */
    @Override
    public ResponseVo sendSecurityCode(String email) {
        log.debug("=====================================================================");
        log.debug("发送验证码");
        try {
            //获取六位数的验证码
            code = EmailUtil.getSecurityCode(6);
            log.debug("获取验证码：" + code);
            //发送验证码
            EmailUtil.sendEmail(email, code);
        } catch (Exception e) {
            log.debug("发送验证码失败：服务器异常，网络不通");
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.SECURITY_CODE_SEND_FAIL);
        }
        log.debug("发送验证码成功");
        log.debug("=====================================================================");
        return new ResponseVo(StatusEnumUtil.SECURITY_CODE_SEND_SUCCESS);
    }

    /**
     * @Name: uploadHeadPortrait
     * @Description: 下载头像文件到服务器，实现上传头像的功能
     * @Param: [request, account, file]
     * @return: com.jackeys.piaems.vo.ResponseVo
     * @Author: Jackeys
     * @Date: 2021/6/23 20:27
     * @Version: 1.0
     */
    @Override
    public ResponseVo uploadHeadPortrait(HttpServletRequest request, String account, MultipartFile file) {
        log.debug("=====================================================================");
        log.debug("上传图片信息");
        String path = null;
        try {
            path = ResourceUtils.getURL("classpath:").getPath() + "resources/files/" + account + "/headImage/";
        } catch (FileNotFoundException e) {
            log.debug("上传失败：找不到文件路径");
            log.debug("=====================================================================");
            e.printStackTrace();
            return new ResponseVo(StatusEnumUtil.USER_UPLOAD_HEAD_PORTRAIT_FAIL);
        }
        String url = request.getContextPath() + "/files/" + account + "/headImage/";
        File filePath = new File(path);
        log.debug("文件保存的路径为：" + path);
        if (!filePath.exists() && !filePath.isDirectory()) {
            log.debug("目录不存在，创建目录：" + filePath);
            filePath.mkdirs(); // mkdir()不会创建目录,找不到相应路径时返回false;而mkdirs()当目录不存在时则会创建相应目录
        }
        //获取原始文件名称(包含格式)
        String originalFileName = file.getOriginalFilename();
        //获取文件类型，以最后一个`.`为标识
        String type = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
        String fileName = SnowFlakeIdUtil.nextId() + "." + type; // 新文件名，这里可以根据需要改名
        //在指定路径下创建一个文件
        File targetFile = new File(path, fileName); // 未使用outputStream.write()的时候,是一个File对象,保存在内存中,硬盘中看不到,但是可以使用这个对象
        try {
            log.debug("上传路径中....");
            // 使用springmvc的transferTo方法上传文件
            file.transferTo(targetFile);
            String imagePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + url + fileName;
            log.debug("上传成功：返回用户图片路径：" + imagePath);
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.USER_UPLOAD_HEAD_PORTRAIT_SUCCESS).add("path", imagePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.debug("上传失败：服务器异常");
        log.debug("=====================================================================");
        return new ResponseVo(StatusEnumUtil.USER_UPLOAD_HEAD_PORTRAIT_FAIL);
    }


    /**
     * @Name: modifyUserInf
     * @Description: 修改用户信息，实现修改用户信息的功能
     * @Param: [account, name, birthday, sex, age, phone, sign, headPortrait]
     * @return: com.jackeys.piaems.vo.ResponseVo
     * @Author: Jackeys
     * @Date: 2021/6/23 20:51
     * @Version: 1.0
     */
    @Override
    public ResponseVo modifyUserInf(String account, String name, Date birthday, String sex, Integer age, String phone, String sign, String headPortrait) {
        log.debug("=====================================================================");
        log.debug("修改用户信息");
        Boolean flag = userDao.updateUserInfByAccount(account, name, birthday, sex, age, phone, sign, headPortrait);
        if (flag) {
            List<User> userList = userDao.getUserInfByAccount(account);
            User user = userList.get(0);
            UserInfDto userInfDto = new UserInfDto.Builder()
                    .id(user.getId())
                    .account(user.getAccount())
                    .age(user.getAge())
                    .birthday(user.getBirthday())
                    .email(user.getEmail())
                    .sex(user.getSex())
                    .headPortrait(user.getHeadPortrait())
                    .name(user.getName())
                    .password(user.getPassword())
                    .phone(user.getPhone())
                    .sign(user.getSign())
                    .build();
            log.debug("修改成功：返回用户信息");
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.USER_UPDATE_INF_SUCCESS).add("user", userInfDto);
        }
        log.debug("修改失败：找不到用户" + account);
        log.debug("=====================================================================");
        return new ResponseVo(StatusEnumUtil.USER_UPDATE_INF_FAIL);
    }

    /**
     * @Name: showHeadPortrait
     * @Description: 查询用户头像，实现登录时展示头像的功能
     * @Param: [account]
     * @return: com.jackeys.piaems.vo.ResponseVo
     * @Author: Jackeys
     * @Date: 2021/6/26 5:42
     * @Version: 1.0
     */
    @Override
    public ResponseVo showHeadPortrait(String account) {
        log.debug("=====================================================================");
        log.debug("查询用户头像");
        String path = userDao.selectHeadPortraitByAccount(account);
        if (path == null || "".equals(path)) {
            log.debug("查询失败：用户默认头像或者用户不存在");
            log.debug("=====================================================================");
            return new ResponseVo(StatusEnumUtil.USER_GET_HEAD_PORTRAIT_FAIL);
        }
        log.debug("查询成功");
        log.debug("=====================================================================");
        return new ResponseVo(StatusEnumUtil.USER_GET_HEAD_PORTRAIT_SUCCESS).add("path", path);
    }
}
